﻿using System;
using System.Collections.Generic;
using System.Reflection;
using Autofac;
using Autofac.Configuration;
using Elasticsearch.Synchronize.Domain.Aggregates.SynchronizeAggregate;
using Elasticsearch.Synchronize.Domain.Events;
using Elasticsearch.Synchronize.Domain.SeedWork;
using Elasticsearch.Synchronize.DomainEventHandler.Handler;
using Elasticsearch.Synchronize.Repository.DBContext;
using Elasticsearch.Synchronize.Repository.Repository;
using Elasticsearch.Synchronize.Repository.Settings;
using MediatR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Json;
using Microsoft.Extensions.Options;
using Module = Autofac.Module;
using Elasticsearch.Synchronize.Job.Tailer;
using Elasticsearch.Synchronize.Common.UUID;
using Elasticsearch.Synchronize.Job.Job;

namespace Elasticsearch.Synchronize.Job
{
    public class ServiceDependencyModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            // 注册autofac.json
            var config = new ConfigurationBuilder();
            // config.AddJsonFile comes from Microsoft.Extensions.Configuration.Json
            // config.AddXmlFile comes from Microsoft.Extensions.Configuration.Xml
            config.AddJsonFile("autofac.json");

            // Register the ConfigurationModule with Autofac.
            var module = new ConfigurationModule(config.Build());
            builder.RegisterModule(module);

            //注册IdGenerator
            builder.RegisterType<IdGenerator>().AsSelf().SingleInstance();

            // 注册DBContext
            builder.Register(c => new MongoDbContext(c.Resolve<MongoDbSettings>()))
                .AsImplementedInterfaces().SingleInstance();

            //注册Repository
            builder.RegisterAssemblyTypes(typeof(SynchronizeItemRepository).Assembly)
                .Where(t => t.Name.EndsWith("Repository"))
                .AsClosedTypesOf(typeof(IRepository<>)).AsImplementedInterfaces().AsSelf().SingleInstance();

            //注册Mediator
            builder.RegisterAssemblyTypes(typeof(IMediator).Assembly)
                .AsImplementedInterfaces();

            builder.Register<SingleInstanceFactory>(ctx =>
            {
                var c = ctx.Resolve<IComponentContext>();
                return t => c.Resolve(t);
            });

            builder.Register<MultiInstanceFactory>(ctx =>
            {
                var c = ctx.Resolve<IComponentContext>();
                return t => (IEnumerable<object>) c.Resolve(typeof(IEnumerable<>).MakeGenericType(t));
            });

            //注册领域事件处理器
            var mediatrOpenTypes = new[]
            {
                typeof(IRequestHandler<,>),
                typeof(IRequestHandler<>),
                typeof(INotificationHandler<>),
            };

            foreach (var mediatrOpenType in mediatrOpenTypes)
            {
                builder
                    .RegisterAssemblyTypes(typeof(ScanSynchronizeItemEventHandler).Assembly)
                    .AsClosedTypesOf(mediatrOpenType)
                    .AsImplementedInterfaces();
            }

            //注册领取对象
            builder.RegisterAssemblyTypes(typeof(SynchronizeRule).Assembly)
                .Where(t => t.IsSubclassOf(typeof(Entity))).AsSelf();

            //注册Tailer
            builder.RegisterAssemblyTypes(this.ThisAssembly)
                .Where(t => t.IsSubclassOf(typeof(BaseTailer))).AsSelf();

            //注册JobServerOption
            builder.Register(r => new JobServerOption()).AsSelf().SingleInstance();

            Console.WriteLine("注入成功了");
        }
    }
}